package com.xw.service.impl;

import cn.hutool.core.util.IdcardUtil;
import cn.hutool.db.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xw.converter.UserStr2UserListDTO;
import com.xw.entity.Reserve;
import com.xw.entity.ReserveItem;
import com.xw.entity.ReserveSetting;
import com.xw.entity.Users;
import com.xw.enums.ResultEnum;
import com.xw.mapper.ReserveItemMapper;
import com.xw.mapper.ReserveMapper;
import com.xw.mapper.ReserveSettingMapper;
import com.xw.mapper.UsersMapper;
import com.xw.service.IReserveService;
import com.xw.utils.R;
import com.xw.vo.ResultVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author y
 * @since 2021-09-15
 */
@Service
public class ReserveServiceImpl extends ServiceImpl<ReserveMapper, Reserve> implements IReserveService {

    @Resource
    private ReserveMapper reserveMapper;

    @Resource
    private ReserveItemMapper reserveItemMapper;

    @Resource
    private UsersMapper usersMapper;

    @Resource
    private ReserveSettingMapper reserveSettingMapper;


    @Override
    @Transactional
    public ResultVO reserveTickets(String openId, String reserveTime, String userList, String remark) {

        Users user = usersMapper.selectOne(new LambdaQueryWrapper<Users>().eq(Users::getOpenid, openId));

        if (user == null) {
            return R.fail();
        }

        List<ReserveSetting> reserveSettingList = reserveSettingMapper.selectList(new LambdaQueryWrapper<ReserveSetting>().eq(ReserveSetting::getReserveTime, reserveTime));
        if (reserveSettingList.isEmpty()) {
            return R.fail(ResultEnum.DATE_NOT_RESERVE);
        }


        Reserve reserve = new Reserve();
        reserve.setOpenid(openId).setReserveTime(reserveTime).setRemark(remark).setNickname(user.getNickname()).setAvatar(user.getAvatar());
        reserveMapper.insert(reserve);

        List<ReserveItem> reserveItemList = UserStr2UserListDTO.convert(userList);
        for (ReserveItem item : reserveItemList) {
            if (!ObjectUtils.isEmpty(item)) {

                if ("身份证".equals(item.getCertificateType())) {
                    if (item.getIdcard().length() == 15) {
                        String convert15To18 = IdcardUtil.convert15To18(item.getIdcard());
                        boolean validCard = IdcardUtil.isValidCard(convert15To18);
                        if (!validCard) {
                            reserveMapper.deleteById(reserve.getId());
                            return R.fail(ResultEnum.VALID_CARD_FAIL, item.getName());

                        }
                    } else {
                        boolean validCard = IdcardUtil.isValidCard(item.getIdcard());
                        if (!validCard) {
                            reserveMapper.deleteById(reserve.getId());
                            return R.fail(ResultEnum.VALID_CARD_FAIL, item.getName());

                        }
                    }
                } else if ("护照".equals(item.getCertificateType())) {

                    if (item.getIdcard().length() != 9) {
                        reserveMapper.deleteById(reserve.getId());
                        return R.fail(ResultEnum.PASSPORT_FORMAT, item.getName());
                    }

                }

                item.setReserveId(reserve.getId());
                item.setReserveTime(reserveTime);
                item.setNickname(user.getNickname());

                //查询当天是否已经有过预约
                LambdaQueryWrapper<ReserveItem> lambdaQueryWrapper = new LambdaQueryWrapper<ReserveItem>();
                lambdaQueryWrapper.eq(ReserveItem::getIdcard, item.getIdcard())
                        .eq(ReserveItem::getReserveTime, reserveTime);

                List<ReserveItem> reserveItem = reserveItemMapper.selectList(lambdaQueryWrapper);
                if (reserveItem.size() != 0) {
                    reserveMapper.deleteById(reserve.getId());
                    return R.fail(ResultEnum.REPEAT_RESERVE, item.getName() + "当天已预约");
                }
            }
        }
        List<ReserveItem> collect = reserveItemList.stream().filter(item -> !ObjectUtils.isEmpty(item)).collect(Collectors.toList());

        List<ReserveSetting> reserveSettings = reserveSettingMapper.selectList(new LambdaQueryWrapper<ReserveSetting>().eq(ReserveSetting::getReserveTime, reserveTime));
        ReserveSetting reserveSetting = reserveSettings.get(0);
        int allNum = reserveSetting.getYetReserveNumber() + collect.size();

        //
        if (allNum > reserveSetting.getReserveNumber()) {
            return R.fail(ResultEnum.RESERVE_FULL);
        }
        collect.forEach(item -> {
            if (!ObjectUtils.isEmpty(item)) {
                int num = reserveSetting.getYetReserveNumber() + 1;
                reserveSetting.setYetReserveNumber(num);
                reserveSettingMapper.updateById(reserveSetting);
                reserveItemMapper.insert(item);
            }
        });

        return R.success();
    }

    @Override
    public ResultVO<?> findReserveList(Page page, HttpServletRequest request) {
        IPage<Reserve> iPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<Reserve>(page.getPageNumber(), page.getPageSize());

        LambdaQueryWrapper<Reserve> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Reserve::getId);

        IPage<Reserve> iP = reserveMapper.selectPage(iPage, queryWrapper);


        for (Reserve item : iP.getRecords()) {

            List<ReserveItem> reserveItemList = reserveItemMapper.selectList(new LambdaQueryWrapper<ReserveItem>().eq(ReserveItem::getReserveId, item.getId()));
            item.setReserveItemList(reserveItemList);

        }

        return R.success(iP.getRecords());
    }

    @Override
    public ResultVO<?> findReserveDate() {

        LambdaQueryWrapper<ReserveSetting> reserveSettingLambdaQueryWrapper = new LambdaQueryWrapper<ReserveSetting>();
        reserveSettingLambdaQueryWrapper.orderByDesc(ReserveSetting::getReserveTime);
        reserveSettingLambdaQueryWrapper.ge(ReserveSetting::getReserveTime, LocalDate.now());

        List<ReserveSetting> reserveSettings = reserveSettingMapper.selectList(reserveSettingLambdaQueryWrapper);
        for (ReserveSetting item : reserveSettings) {
            int num = item.getReserveNumber() - item.getYetReserveNumber();
            if (num <= 0) {
                item.setSurplusReserveNumber(0);
            } else {
                item.setSurplusReserveNumber(num);

            }
        }

        return R.success(reserveSettings);
    }

    @Override
    public ResultVO<?> findReserveItemList(String openId) {

        List<Reserve> reserves = reserveMapper.selectList(new LambdaQueryWrapper<Reserve>().eq(Reserve::getOpenid, openId).orderByDesc(Reserve::getReserveTime).orderByDesc(Reserve::getId));

        for (Reserve item : reserves) {
            List<ReserveItem> reserveItems = reserveItemMapper.selectList(new LambdaQueryWrapper<ReserveItem>().eq(ReserveItem::getReserveId, item.getId()));
            item.setReserveItemList(reserveItems);
        }

        return R.success(reserves);
    }
}
